using System;
using System.Runtime.InteropServices;

namespace Microsoft.Windows.SyncManager.Interop
{
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("6295DF2C-35EE-11d1-8707-00C04FD93327")]
	public interface ISyncMgrSynchronizeInvoke
	{
		void UpdateItems(
			uint InvokeFlags,
			ref Guid rclsid,
			uint cookieSize,
			[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)]
			byte[] cookie
			);

		void UpdateAll();
	}

	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("6295DF40-35EE-11d1-8707-00C04FD93327")]
	public interface ISyncMgrSynchronize 
	{
		void Initialize(
			uint reserved,
			SYNCMGRFLAG syncMgrFlags,
			uint cookieSize,
			[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)]
			byte[] cookie
			);

		void GetHandlerInfo(
			out SYNCMGRHANDLERINFO syncMgrHandlerInfo
			);

		void EnumSyncMgrItems( 
			out ISyncMgrEnumItems syncMgrItemEnumerator 
			);

		void GetItemObject(
			ref Guid itemID,
			ref Guid guid,
			out IntPtr item
			);
  
		void ShowProperties(
			IntPtr hWndParent,
			ref Guid itemID
			);
		
		void SetProgressCallback(
			ISyncMgrSynchronizeCallback callback
			);

		void PrepareForSync(
			int numItems,
			[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
			Guid[] itemIds,
			IntPtr hWndParent,
			uint reserved
			);

		void Synchronize(
			IntPtr hWndParent
			);
	
		void SetItemStatus(
			ref Guid itemID,
			SYNCMGRSTATUS syncMgrStatus
			);

		void ShowError(
			IntPtr hWndParent,
			ref Guid errorID
			);
	}

	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("6295DF2A-35EE-11d1-8707-00C04FD93327")]
	public interface ISyncMgrEnumItems
	{
		[PreserveSig]
		int Next(
			int count
			,[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
			SYNCMGRITEM[] items
			, out int fetched);
 
		void Skip(int count);

		void Reset();

		void Clone(
			out ISyncMgrEnumItems ppEnum
			);
	}

	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("6295DF41-35EE-11d1-8707-00C04FD93327")]
	public interface ISyncMgrSynchronizeCallback
	{
		void ShowPropertiesCompleted(
			int hr
			);

		void PrepareForSyncCompleted(
			int hr
			);

		void SynchronizeCompleted(
			int hr
			);

		void ShowErrorCompleted(
			int hr,
			uint numItems,
			[MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
			Guid[] itemIds
			);

		void EnableModeless(
			[MarshalAs(UnmanagedType.Bool)]
			bool enable
			);

		int Progress(
			ref Guid itemID,
			ref SyncMgrProgressItem syncProgressItem
			);

		void LogError(
			SYNCMGRLOGLEVEL errorLevel,
			string errorText,
			SYNCMGRLOGERRORINFO syncLogError
			);

		void DeleteLogError(
			ref Guid errorID,
			uint reserved
			);

		void EstablishConnection(
			string connection,
			uint reserved
			);
	}

	[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
	public class SYNCMGRHANDLERINFO 
	{
		protected int	cbSize = Marshal.SizeOf( typeof( SYNCMGRHANDLERINFO ) );
		public IntPtr	hIcon;
		public SYNCMGRHANDLERFLAGS SyncMgrHandlerFlags;
		[MarshalAs( UnmanagedType.ByValTStr, SizeConst=32 )]
		public string HandlerName;
	}

	[Flags]
	public enum SYNCMGRHANDLERFLAGS : uint
	{   // flags that apply to this handler.
		HASPROPERTIES          = 0x01,   // have a properties dialog for this handler
		MAYESTABLISHCONNECTION = 0x02,   // may call callback EstablishConnection method
		ALWAYSLISTHANDLER      = 0x04,   // Show Handler in Choice even if not items    
	}

	public enum SYNCMGRSTATUS : uint
	{
		STOPPED		= 0,
		SKIPPED		= 0x1,
		PENDING		= 0x2,
		UPDATING	= 0x3,
		SUCCEEDED	= 0x4,
		FAILED		= 0x5,
		PAUSED		= 0x6,
		RESUMING	= 0x7,
		DELETED		= 0x100
	}

	[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
	public struct SYNCMGRITEM
	{
		public int cbSize;
		public SYNCMGRITEMFLAGS Flags;
		public Guid ItemID;
		public SYNCMGRITEMSTATE ItemState;
		public IntPtr hIcon;
		[MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]
		public string ItemName;
		public FILETIME LastUpdate;
	}

	public enum SYNCMGRITEMSTATE : uint 
	{
		UNCHECKED     = 0x0000,
		CHECKED       = 0x0001
	}

	[Flags]
	public enum SYNCMGRITEMFLAGS : uint
	{
		HASPROPERTIES	= 0x1,
		TEMPORARY		= 0x2,
		ROAMINGUSER		= 0x4,
		LASTUPDATETIME	= 0x8,
		MAYDELETEITEM	= 0x10
	}

	public enum SYNCMGRLOGLEVEL
	{
		 SYNCMGRLOGLEVEL_INFORMATION	= 1
		,SYNCMGRLOGLEVEL_WARNING		= 2
		,SYNCMGRLOGLEVEL_ERRORS			= 3
	}

	[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
	public class SYNCMGRLOGERRORINFO
	{
		protected int Size = Marshal.SizeOf( typeof(SYNCMGRLOGERRORINFO) );
		public SYNCMGRLOGERROR Mask;
		public SYNCMGRERRORFLAGS SyncMgrErrorFlags;
		public Guid ErrorID;
		public Guid ItemID;
	}

	[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
	public struct SyncMgrProgressItem
	{
		public int Size;
		public SYNCMGRPROGRESSITEMMASK Mask;
		public string StatusText;   
		public SYNCMGRSTATUS StatusType;
		public int ProgValue;
		public int MaxValue;
	}

	public enum SYNCMGRPROGRESSITEMMASK : uint
	{
		 STATUSTEXT     =0x0001
		,STATUSTYPE     =0x0002
		,PROGVALUE      =0x0004
		,MAXVALUE       =0x0008
	}

	[Flags]
	public enum SYNCMGRFLAG : uint
	{
		CONNECT				= 0x0001, 
		PENDINGDISCONNECT	= 0x0002, 
		MANUAL				= 0x0003, 
		IDLE				= 0x0004, 
		INVOKE				= 0x0005, 
		SCHEDULED			= 0x0006, 
		EVENTMASK			= 0x00FF, 
		SETTINGS			= 0x0100, 
		MAYBOTHERUSER		= 0x0200
	}

	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("6295DF42-35EE-11d1-8707-00C04FD93327")]
	public interface ISyncMgrRegister
	{
		void RegisterSyncMgrHandler(
			ref Guid handler,
			[MarshalAs(UnmanagedType.LPWStr)]
			string Description,
			uint syncMgrRegisterFlags
			);

		void UnregisterSyncMgrHandler(
			ref Guid handler,
			uint reserved
			);

		void GetHandlerRegistrationInfo(
			ref Guid handler,
			ref uint syncMgrRegisterFlags);
	}

	public enum SYNCMGRLOGERROR : uint
	{
		SYNCMGRLOGERROR_ERRORFLAGS	= 0x0001,
		SYNCMGRLOGERROR_ERRORID		= 0x0002,
		SYNCMGRLOGERROR_ITEMID		= 0x0004
	}

	public enum SYNCMGRERRORFLAGS : uint
	{
		EnableJumpText = 0x01 
	}
}
